/*
 * Created: Author: Aléx Carvalho / Date: Apr 15, 2015
 * 
 * Changed: $Author: ac280593@gmail.com $ / $Date: 2015-06-11 04:34:08 +0000 (Thu, 11 Jun 2015) $
 */
package com.cpm.repository.jpa;

import com.cpm.entities.Indicator;
import com.cpm.entities.Node;
import com.cpm.entities.Node_;
import com.cpm.repository.NodeRepository;
import java.util.Collection;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

public class NodeRepositoryJpa extends GenericCrudRepositoryJpa<Node> implements NodeRepository {

    @Transactional
    @Override
    public void updatePosition(Node value) {
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaUpdate criteriaUpdate = builder.createCriteriaUpdate(value.getClass());
        Root<Indicator> root = criteriaUpdate.from(value.getClass());
        criteriaUpdate.set(Node_.position, value.getPosition());
        criteriaUpdate.where(builder.equal(root.get(Node_.id), value.getId()));
        Query query = entityManager.createQuery(criteriaUpdate);
        query.executeUpdate();
    }

    @Transactional
    @Override
    public void updatePosition(Collection<Node> values) {

        Node value = values.stream().findFirst().get();

//        QueryUpdate d = QueryUpdate.factory(Indicator.class);
        
//        LinkedList<Long> ids = values.stream().map( Node::getId).collect(Collectors.toList());
//        
//        values.forEach( no -> ids.add(no.getId()));
//        
//        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
//        CriteriaUpdate criteriaUpdate = builder.createCriteriaUpdate(value.getClass());
//        Root<Indicator> root = criteriaUpdate.from(value.getClass());
//        criteriaUpdate.set(Node_.position, builder.selectCase().when(builder.equal(root.get(Node_.id), 1),1).otherwise(0) );
//        criteriaUpdate.where(builder.equal(root.get(Node_.id), root.in(ids) ));
//        Query query = entityManager.createQuery(criteriaUpdate);
//        query.executeUpdate();
        StringBuilder sql = new StringBuilder("update " + value.getClass().getSimpleName() + " set " + Node_.position.getName() + " = CASE " + Node_.id.getName());
        StringBuilder ids = new StringBuilder();

        values.forEach(no -> {
            sql.append(" WHEN ").append(no.getId()).append(" THEN ").append(no.getPosition());
            ids.append(no.getId()).append(", ");
        });

        sql.append(" END WHERE ").append(Node_.id.getName()).append(" in (").append(ids.substring(0, ids.lastIndexOf(","))).append(")");
        Query query = entityManager.createQuery(sql.toString());
        query.executeUpdate();
    }

    @Transactional
    @Override
    public void updatePositionAndParent(Node value) {
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaUpdate criteriaUpdate = builder.createCriteriaUpdate(value.getClass());
        Root<Indicator> root = criteriaUpdate.from(value.getClass());
        criteriaUpdate.set(Node_.position, value.getPosition());
        criteriaUpdate.set(Node_.parentFamily, value.getParentFamily());
        criteriaUpdate.set(Node_.parentId, value.getParentId());
        criteriaUpdate.where(builder.equal(root.get(Node_.id), value.getId()));
        Query query = entityManager.createQuery(criteriaUpdate);
        query.executeUpdate();
    }

//        criteriaUpdate.set(Node_.position, builder.selectCase().when(builder.equal(root.get(Node_.id), 1),1).otherwise(0) );
//        criteriaUpdate.where(builder.equal(root.get(Node_.id), root.in(ids) ));
//    UPDATE `indicator`
//    SET `position` = CASE id
//        WHEN 1 THEN 2
//        WHEN 2 THEN 7
//        WHEN 3 THEN 9
//    END
//WHERE id IN (1,2,3)
}
